<!DOCTYPE html>
<html>
  <head>
    <title>对象</title>
    <style></style>
  </head>
  <body>
    <script>
      // 仅挑选部分
      let obj = {}

      //   可枚举性
      //   对象的每个属性都有一个描述对象
      //   其中，enumerable被称为可枚举性
      obj = {
        a: 1,
        b: 2,
        c: 3,
        d: 4,
        [Symbol('new symbol')]: 5,
      }
      console.log(Object.getOwnPropertyDescriptor(obj, 'a'))
      Object.defineProperty(obj, 'a', {
        enumerable: false,
      })
      console.log(Object.getOwnPropertyDescriptors(obj))
      console.log('------------------------------------')

      //   当enumerable为false时，以下四种操作会跳过当前属性
      //   for...in...  仅有该方法会返回继承的属性
      //   Object.keys
      //   JSON.stringify
      //   Object.assign
      //   并且，ES6规定所有原型方法都是不可枚举的。引入继承会打破这种情况，所以尽量不要使用for...in...来循环
      //   -----------------------------------------------------------------

      //   对象循环
      //   有5种方法，遍历顺序一致：先数字(升序)，再字符(加入时间)，再symbol(加入时间)
      //   for...in...  键，自身及继承的可枚举属性（不含symbol）
      //   Object.keys(obj) 自身的可枚举属性（不含symbol）
      console.log(Object.keys(obj)) // b c d
      //   Object.getOwnPropertyNames(obj) 自身所有属性的键名，包括不可枚举的（不含symbol）
      console.log(Object.getOwnPropertyNames(obj)) // a b c d
      //   Object.getOwnPropertySymbols(obj) 自身所有symbol属性的键名
      console.log(Object.getOwnPropertySymbols(obj)) // [Symbol(new symbol)]
      //   Reflect.ownKeys(obj) 自身所有属性，无论是否可以枚举，也不管是不是symbol
      console.log(Reflect.ownKeys(obj)) // a b c d [Symbol(new symbol)]
      console.log('------------------------------------')

      console.log('------------object新增方法-----------')
      //   Object.is()   '==='判断符的优化，除了+0不等于-0，NaN等于自身，其他没区别
      console.log('Object.is({}, {}):   ', Object.is({}, {}))
      console.log('------------------------------------')

      //   Object.assign()      将源对象所有可枚举属性，复制到目标对象；同名则替换覆盖（而不是合并）；！！！浅拷贝
      //   保持继承链的克隆
      //   function clone(origin) {
      //     let originProto = Object.getPrototypeOf(origin)
      //     return Object.assign(Object.create(originProto), origin)
      //   }

      //   Object.setPrototypeOf(source, target)    设置对象的原型
      //   Object.getPrototypeOf()   读取一个对象的原型

      //   遍历方法
      // Object.keys()，Object.values()，Object.entries()   这三个获取规则一致，不继承、只有可枚举、无symbol
      console.log(Object.values(obj), Object.entries(obj))
      console.log('------------------------------------')

      //   Object.fromEntries()   将键值对数组还原为对象
      console.log(Object.fromEntries(new URLSearchParams('foo=bar&baz=qux'))) // { foo: "bar", baz: "qux" }
      console.log('------------------------------------')

      //   hasOwnProperty()   判断是否在原型链上
      //   Object.hasOwn()    判断是否是自身属性
      console.log(Object.hasOwn(obj, "a"))
    </script>
  </body>
</html>
